/**
 * 项目申请服务
 * 处理项目申请的业务逻辑
 */

// 使用统一配置入口引用模型
const { ProjectApplyModel, ProjectApplyTypes } = require('../../config/models_config');
const ProjectService = require('./project_service.js');
const dayjs = require('dayjs');

/**
 * 项目申请服务类
 */
class ProjectApplyService {
  /**
   * 创建项目申请
   * @param {Object} formData 表单数据
   * @returns {Promise<Object>} 申请结果
   */
  static async createApply(formData) {
    try {
      // 1. 处理表单数据
      const processedData = this._processApplyFormData(formData);
      
      // 2. 获取项目类型默认参数
      const defaultParams = ProjectService.getProjectDefaultParams(processedData.applicationType);
      
      // 3. 合并表单数据和默认参数
      const mergedData = {
        ...defaultParams,
        ...processedData
      };
      
      // 4. 创建项目申请
      const result = await ProjectApplyModel.createApply(mergedData);
      
      return result;
    } catch (e) {
      console.error('[项目申请服务] 创建申请失败:', e);
      throw e;
    }
  }
  
  /**
   * 提交项目申请审核
   * @param {String} applyId 申请ID
   * @returns {Promise<Object>} 处理结果
   */
  static async submitApply(applyId) {
    try {
      return await ProjectApplyModel.submitApply(applyId);
    } catch (e) {
      console.error('[项目申请服务] 提交申请失败:', e);
      throw e;
    }
  }
  
  /**
   * 获取项目申请进度
   * @param {String} applyId 申请ID
   * @returns {Promise<Object>} 申请进度信息
   */
  static async getApplyProgress(applyId) {
    try {
      // 1. 获取申请详情
      const applyDetail = await ProjectApplyModel.getApplyDetail(applyId);
      
      // 2. 获取申请历史
      const applyHistory = await ProjectApplyModel.getApplyHistory(applyId);
      
      // 3. 处理进度信息
      const progressInfo = this._processApplyProgress(applyDetail, applyHistory);
      
      return progressInfo;
    } catch (e) {
      console.error('[项目申请服务] 获取申请进度失败:', e);
      throw e;
    }
  }
  
  /**
   * 获取项目申请详情
   * @param {String} applyId 申请ID
   * @returns {Promise<Object>} 申请详情
   */
  static async getApplyDetail(applyId) {
    try {
      // 1. 获取申请基本信息
      const applyDetail = await ProjectApplyModel.getApplyDetail(applyId);
      
      // 2. 处理显示信息
      return this._processApplyDisplay(applyDetail);
    } catch (e) {
      console.error('[项目申请服务] 获取申请详情失败:', e);
      throw e;
    }
  }
  
  /**
   * 获取项目申请列表
   * @param {Object} params 查询参数
   * @returns {Promise<Object>} 申请列表
   */
  static async getApplyList(params = {}) {
    try {
      // 1. 获取申请列表
      const result = await ProjectApplyModel.getApplyList(params);
      
      // 2. 处理列表数据
      if (result && result.data && Array.isArray(result.data)) {
        result.data = result.data.map(item => this._processApplyDisplay(item));
      }
      
      return result;
    } catch (e) {
      console.error('[项目申请服务] 获取申请列表失败:', e);
      throw e;
    }
  }
  
  /**
   * 更新项目申请
   * @param {Object} data 更新数据
   * @returns {Promise<Object>} 处理结果
   */
  static async updateApply(data) {
    try {
      // 1. 处理表单数据
      const processedData = this._processApplyFormData(data);
      
      // 2. 更新申请数据
      return await ProjectApplyModel.updateApply(processedData);
    } catch (e) {
      console.error('[项目申请服务] 更新申请失败:', e);
      throw e;
    }
  }
  
  /**
   * 触发项目申请状态变更事件
   * @param {String} applyId 申请ID
   * @param {String} eventCode 事件代码
   * @param {Object} eventData 事件数据
   * @returns {Promise<Object>} 处理结果
   */
  static async triggerApplyEvent(applyId, eventCode, eventData = {}) {
    try {
      return await ProjectApplyModel.triggerEvent(applyId, eventCode, eventData);
    } catch (e) {
      console.error('[项目申请服务] 触发事件失败:', e);
      throw e;
    }
  }
  
  /**
   * 上传项目申请文件
   * @param {String} applyId 申请ID
   * @param {String} fileType 文件类型
   * @param {Object} fileData 文件数据
   * @returns {Promise<Object>} 处理结果
   */
  static async uploadApplyFile(applyId, fileType, fileData) {
    try {
      return await ProjectApplyModel.uploadApplyFile(applyId, fileType, fileData);
    } catch (e) {
      console.error('[项目申请服务] 上传文件失败:', e);
      throw e;
    }
  }
  
  /**
   * 处理申请表单数据
   * @param {Object} formData 表单数据
   * @returns {Object} 处理后的数据
   * @private
   */
  static _processApplyFormData(formData) {
    // 复制数据，避免修改原始对象
    const data = { ...formData };
    
    // 处理日期时间字段
    if (data.startDate && typeof data.startDate === 'string') {
      data.startDate = dayjs(data.startDate).valueOf();
    }
    
    if (data.deadline && typeof data.deadline === 'string') {
      data.deadline = dayjs(data.deadline).valueOf();
    }
    
    // 统一字段名称
    if (data.name && !data.PROJECT_TITLE) {
      data.PROJECT_TITLE = data.name;
    }
    
    if (data.customerName && !data.PROJECT_CUSTOMER_NAME) {
      data.PROJECT_CUSTOMER_NAME = data.customerName;
    }
    
    if (data.description && !data.PROJECT_DESC) {
      data.PROJECT_DESC = data.description;
    }
    
    // 确保有申请类型
    if (!data.APPLY_TYPE && data.applicationType) {
      data.APPLY_TYPE = ProjectApplyTypes.getApplyTypeByProjectType(data.applicationType);
    }
    
    return data;
  }
  
  /**
   * 处理申请进度信息
   * @param {Object} applyDetail 申请详情
   * @param {Array} applyHistory 申请历史
   * @returns {Object} 进度信息
   * @private
   */
  static _processApplyProgress(applyDetail, applyHistory) {
    if (!applyDetail) return null;
    
    // 基础信息
    const progressInfo = {
      applyId: applyDetail._id,
      currentStatus: applyDetail.APPLY_STATUS,
      currentStatusName: applyDetail.APPLY_STATUS_NAME,
      currentActiveStatus: applyDetail.APPLY_ACTIVE_STATUS,
      currentActiveStatusName: applyDetail.APPLY_ACTIVE_STATUS_NAME,
      history: [],
      timeline: [],
      progress: 0, // 0-100的进度值
      nextEvents: [] // 可执行的下一步事件
    };
    
    // 计算进度值
    const totalSteps = Object.keys(ProjectApplyTypes.PROJECT_STATUS).length;
    const currentStep = Object.values(ProjectApplyTypes.PROJECT_STATUS).indexOf(applyDetail.APPLY_STATUS) + 1;
    progressInfo.progress = Math.round((currentStep / totalSteps) * 100);
    
    // 处理历史记录
    if (Array.isArray(applyHistory)) {
      // 按时间排序
      const sortedHistory = [...applyHistory].sort((a, b) => a.CREATE_TIME - b.CREATE_TIME);
      
      // 构建时间线
      progressInfo.timeline = sortedHistory.map(item => ({
        time: dayjs(item.CREATE_TIME).format('YYYY-MM-DD HH:mm'),
        event: item.EVENT_NAME || '状态变更',
        from: item.FROM_STATUS_NAME || '',
        to: item.TO_STATUS_NAME || '',
        operator: item.OPERATOR_NAME || '',
        comment: item.COMMENT || ''
      }));
      
      // 保存原始历史数据
      progressInfo.history = sortedHistory;
    }
    
    // 获取可执行的下一步事件
    progressInfo.nextEvents = this._getNextAvailableEvents(applyDetail);
    
    return progressInfo;
  }
  
  /**
   * 获取下一步可执行的事件
   * @param {Object} applyDetail 申请详情
   * @returns {Array} 事件列表
   * @private
   */
  static _getNextAvailableEvents(applyDetail) {
    if (!applyDetail) return [];
    
    const { APPLY_STATUS, APPLY_ACTIVE_STATUS, applicationType } = applyDetail;
    
    // 获取项目类型的流程定义
    const statusFlow = ProjectApplyTypes.getDefaultStatusFlowByType(applicationType);
    
    // 找出当前状态可执行的下一步事件
    const nextEvents = statusFlow.filter(flow => 
      flow.status === APPLY_STATUS && flow.activeStatus === APPLY_ACTIVE_STATUS
    ).map(flow => ({
      eventCode: flow.nextEvent,
      eventName: ProjectApplyTypes.EVENT_NAMES[flow.nextEvent] || flow.nextEvent,
      nextStatus: flow.nextStatus,
      nextStatusName: ProjectApplyTypes.PROJECT_STATUS_NAMES[flow.nextStatus] || '',
      nextActiveStatus: flow.nextActiveStatus,
      nextActiveStatusName: ProjectApplyTypes.ACTIVE_STATUS_NAMES[flow.nextActiveStatus] || ''
    }));
    
    // 添加通用事件
    const commonEvents = [];
    
    // 如果是草稿或规划中状态，可以取消
    if (APPLY_STATUS === ProjectApplyTypes.PROJECT_STATUS.PLANNING) {
      commonEvents.push({
        eventCode: ProjectApplyTypes.EVENTS.CANCEL,
        eventName: ProjectApplyTypes.EVENT_NAMES[ProjectApplyTypes.EVENTS.CANCEL],
        nextStatus: ProjectApplyTypes.PROJECT_STATUS.CANCELLED,
        nextStatusName: ProjectApplyTypes.PROJECT_STATUS_NAMES[ProjectApplyTypes.PROJECT_STATUS.CANCELLED],
        nextActiveStatus: 0,
        nextActiveStatusName: '已取消'
      });
    }
    
    // 如果是开发中或测试中状态，可以申请休眠
    if (APPLY_STATUS === ProjectApplyTypes.PROJECT_STATUS.DEVELOPMENT || 
        APPLY_STATUS === ProjectApplyTypes.PROJECT_STATUS.TESTING) {
      commonEvents.push({
        eventCode: ProjectApplyTypes.EVENTS.SLEEP_REQUEST,
        eventName: ProjectApplyTypes.EVENT_NAMES[ProjectApplyTypes.EVENTS.SLEEP_REQUEST],
        nextStatus: APPLY_STATUS,
        nextStatusName: ProjectApplyTypes.PROJECT_STATUS_NAMES[APPLY_STATUS],
        nextActiveStatus: 0,
        nextActiveStatusName: '休眠申请中'
      });
    }
    
    return [...nextEvents, ...commonEvents];
  }
  
  /**
   * 处理申请显示信息
   * @param {Object} applyData 申请数据
   * @returns {Object} 处理后的数据
   * @private
   */
  static _processApplyDisplay(applyData) {
    if (!applyData) return null;
    
    const displayData = { ...applyData };
    
    // 处理日期显示
    if (displayData.startDate) {
      displayData.startDateDisplay = dayjs(displayData.startDate).format('YYYY-MM-DD');
    }
    
    if (displayData.deadline) {
      displayData.deadlineDisplay = dayjs(displayData.deadline).format('YYYY-MM-DD');
    }
    
    if (displayData.APPLY_TIME) {
      displayData.applyTimeDisplay = dayjs(displayData.APPLY_TIME).format('YYYY-MM-DD HH:mm');
    }
    
    if (displayData.APPLY_UPDATE_TIME) {
      displayData.updateTimeDisplay = dayjs(displayData.APPLY_UPDATE_TIME).format('YYYY-MM-DD HH:mm');
    }
    
    // 处理状态链显示
    if (displayData.APPLY_STATUS && displayData.APPLY_ACTIVE_STATUS) {
      const statusName = ProjectApplyTypes.PROJECT_STATUS_NAMES[displayData.APPLY_STATUS] || '';
      const activeStatusName = ProjectApplyTypes.ACTIVE_STATUS_NAMES[displayData.APPLY_ACTIVE_STATUS] || '';
      
      displayData.statusChain = [statusName, activeStatusName].filter(Boolean);
    }
    
    return displayData;
  }
}

module.exports = ProjectApplyService; 